#!/usr/bin/perl -w
use strict;
use DBI;
use DBD::Pg;
use FindBin;
use lib ("$FindBin::Bin/..", "/net/cpp-group/Leo/bin");
use chromosomes;
use linewrap;
use die_error;

use db_parameters;
use ortho_species;

print STDERR <<"HEADLINE";
888888888888888888888888888888888888888888888888888888888888888888888

    table_predicted_type


    depend on
        ens_id
		
888888888888888888888888888888888888888888888888888888888888888888888
HEADLINE

#
#	Connect to genome database
#
my $dbh = connect_to_panda();
use get_psql_time;
my $start_time = get_psql_time($dbh);





#
#	Update split genes
#
sub update_split_genes($)
{
	my ($dbh) = @_;
	print STDERR "\tUpdate lists of split genes in phylip\n";
	$dbh->do( <<"PL/SQLCMD" );
    DELETE from orthologs.split_genes WHERE protocol_id = $curr_protocol_id;
    INSERT INTO 
        orthologs.split_genes 
            (gene_id, disentangled_gene_id, prot_id, protocol_id)  
            SELECT 
                gene_id, 
                gene_id || '&' || prot_id, 
                prot_id,
                $curr_protocol_id
            FROM 
                orthologs.ortholog_sets 
            WHERE 
                gene_id IN 
                (
                    SELECT 
                            gene_id 
                        FROM
                            orthologs.ortholog_sets 
                        WHERE 
                            protocol_id = $curr_protocol_id
                        GROUP BY 
                            gene_id 
                        HAVING COUNT(*) > 1
                );
PL/SQLCMD
}





#
#	predicted_type_defaults_to_orphan_no_homolog
#
#		get list of all genes from ens_id
#		for split genes, only include disentangled_gene_ids
#
sub predicted_type_defaults_to_orphan_no_homolog($)
{
	my ($dbh) = @_;
	
	my $sql_cmd = <<"PL/SQLCMD";
	INSERT INTO 
        orthologs.predicted_type(gene_id, disentangled_gene_id, species, protocol_id, gene_type)
    	SELECT 
        		DISTINCT ON (gene_id) 
        		gene_id,
        		gene_id,
                species,
        		$curr_protocol_id,
        		'Orphan No homolog'
    	    FROM 
    			ens_id 
            WHERE
                species = '$ortho_name1' or
                species = '$ortho_name2';
PL/SQLCMD
	$dbh->do($sql_cmd);
	print STDERR "\t\tDelete merged genes from set...\n";
	$sql_cmd = <<"PL/SQLCMD";
	DELETE 
        FROM 
            predicted_type 
                USING 
            split_genes 
        WHERE 
            split_genes.gene_id = predicted_type.gene_id AND 
            split_genes.protocol_id = predicted_type.protocol_id AND
            predicted_type.protocol_id = $curr_protocol_id;
        
    INSERT INTO 
        orthologs.predicted_type(gene_id, disentangled_gene_id, species, protocol_id, gene_type)
        SELECT 
                DISTINCT ON (disentangled_gene_id) 
                gene_id,
                disentangled_gene_id,
                species,
                $curr_protocol_id,
                'Orphan No homolog'
            FROM 
                ens_id NATURAL JOIN 
                split_genes
            WHERE
                species = '$ortho_name1' or
                species = '$ortho_name2';
PL/SQLCMD
	$dbh->do($sql_cmd);
}



#
#	tag which genes survived past which pipeline stage
#
sub update_genes_with_pipeline_stage($)
{
	my ($dbh) = @_;
	my @phyop_stage_gene_type = (
									['blast_filtered'				, 'Orphan homolog within species'],
									['blast_other_species'			, 'Orphan homolog other species'],
									['kaks_filtered'				, 'Orphan low dS homolog within species'],
									['kaks_filtered_other_species'	, 'Orphan low dS homolog other species'],
									['ortholog_clades'				, 'Orphan paralog within ortholog clade'],
									['ortholog_clades_other_species', 'Orphan within ortholog clade']);
	for my $phyop_stage_gene_type (@phyop_stage_gene_type)
	{
		my ($phyop_stage, $gene_type) = @$phyop_stage_gene_type;
		my @genes;
		for my $species_name($ortho_name1, $ortho_name2)
		{
			my $file_name = "$dir_orthologs_output/gene_lists/".
							"$phyop_stage.$species_name.genes";
			die_error "Could not find $file_name.\n" unless (-f $file_name);
			open GENES, $file_name or die;
			my @taxon_genes = <GENES>;
			chomp(@taxon_genes);
			push(@genes,  @taxon_genes);
		}

		# no genes: ignore
		next unless @genes;
		
		$dbh->do("CREATE TEMP TABLE t1(gene_id TEXT);");
		$dbh->do("COPY t1 FROM STDIN;");
		$dbh->pg_putline("$_\n") for (@genes);
		$dbh->pg_endcopy();

		print STDERR "\t\tSet gene types for <$gene_type>...\n";
		my $sql_cmd = <<"PL/SQLCMD";
		CREATE INDEX it1 ON t1(gene_id);
		ANALYSE t1;
		UPDATE
				orthologs.predicted_type
			SET
				gene_type = '$gene_type'
			FROM
				t1
			WHERE
				orthologs.predicted_type.gene_id = t1.gene_id AND
				protocol_id = $curr_protocol_id;
PL/SQLCMD
		$dbh->do($sql_cmd);
		$dbh->do("DROP TABLE t1;");
	}
}


#
#	Fill predicted types from ortholog set types
#
sub predicted_type_from_ortholog_set($)
{
	my ($dbh) = @_;
	my $sql_cmd = <<"PL/SQLCMD";
	-- Update predicted_type
	UPDATE 
			orthologs.predicted_type 
		SET 
			gene_type = orthologs.ortholog_sets.ortholog_type 
		FROM
			orthologs.ortholog_sets
		WHERE
			orthologs.predicted_type.disentangled_gene_id  = orthologs.ortholog_sets.disentangled_gene_id AND 
			orthologs.predicted_type.protocol_id = orthologs.ortholog_sets.protocol_id;
	VACUUM ANALYSE orthologs.predicted_type;
PL/SQLCMD
	$dbh->do( $sql_cmd) or die;
}


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888


#			Main logic starts here


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888




$dbh->do("DELETE FROM orthologs.predicted_type where protocol_id = $curr_protocol_id;");
$dbh->do("VACUUM ANALYSE orthologs.predicted_type;");

#
#	Get protocol name
#
my $protocol_name = get_orthologs_protocol_name($curr_protocol_id);



print STDERR "\tOrthology protocol [$protocol_name]...\n";

#
#	Update list of split genes
#
print STDERR "\tUpdate list of split genes\n";
update_split_genes($dbh);


#
#	get list of all genes (including those which have been split up)
#		and set them to 'Orphan no homolog'
#
predicted_type_defaults_to_orphan_no_homolog($dbh);


#
#	tag which genes survived past which pipeline stage
#
update_genes_with_pipeline_stage($dbh);



#
#	copy ortholog_set ortholog_types into predicted type
#
predicted_type_from_ortholog_set($dbh);

log_pipeline_stage($dbh, $curr_protocol_id, 35, 'table predicted_type', $start_time);
$dbh->disconnect();



 
